package com.quad.innovators.salesease.service.impl.base;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quad.innovators.salesease.common.result.PageResultBean;
import com.quad.innovators.salesease.common.utils.SystemCodeUtils;
import com.quad.innovators.salesease.converter.ProductConverter;
import com.quad.innovators.salesease.enums.ResultCode;
import com.quad.innovators.salesease.enums.StatusEnum;
import com.quad.innovators.salesease.enums.SystemCodeEnum;
import com.quad.innovators.salesease.exception.BusinessException;
import com.quad.innovators.salesease.mapper.base.ProductMapper;
import com.quad.innovators.salesease.model.common.Option;
import com.quad.innovators.salesease.model.entity.base.BrandProvider;
import com.quad.innovators.salesease.model.entity.base.Product;
import com.quad.innovators.salesease.model.form.base.ProductForm;
import com.quad.innovators.salesease.model.query.base.ProductPageQuery;
import com.quad.innovators.salesease.model.vo.base.ProductVO;
import com.quad.innovators.salesease.service.base.ProductService;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final ProductConverter productConverter;

    @Override
    public PageResultBean<ProductVO> listPaged(ProductPageQuery queryParams) {
        Page<ProductVO> productPage = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        Page<ProductVO> productVOPage = this.baseMapper.listPaged(productPage, queryParams);
        return productConverter.toPageVo(productVOPage);
    }

    @Override
    public boolean save(ProductForm form) {
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Product>()
                .eq(Product::getName, form.getName())
        );
        if (count > 0) {
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Product entity = productConverter.toEntity(form);
        entity.setCode(SystemCodeUtils.getCode(SystemCodeEnum.PRODUCT));
        this.baseMapper.insert(entity);
        return true;
    }

    @Override
    public ProductForm getFormData(String code) {
        Product product = this.baseMapper.selectByCode(code);
        if (product == null) {
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        return productConverter.toForm(product);
    }

    @Override
    public boolean update(String code, ProductForm form) {
        Product formData = this.baseMapper.selectByCode(code);
        if (formData == null) {
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        // 是否已经存在
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Product>()
                .eq(Product::getName, form.getName())
                .ne(Product::getCode, code)
        );
        if (count > 0) {
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Product entity = productConverter.toEntity(form);
        entity.setId(formData.getId());
        this.baseMapper.updateById(entity);
        return true;
    }

    @Override
    public boolean updateStatus(String code, Integer status) {
        Product formData = this.baseMapper.selectByCode(code);
        if (formData == null) {
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        formData.setStatus(status);
        this.baseMapper.updateById(formData);
        return true;
    }


    @Override
    public List<Option<String>> listOptions() {
        List<Product> brandProviders = this.baseMapper.selectList(new QueryWrapper<Product>().lambda().eq(Product::getStatus, StatusEnum.ENABLE.getValue()));
        return brandProviders.stream().map(it -> new Option<>(it.getCode(), it.getName())).collect(Collectors.toList());
    }
}
